home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
4_0
/
GREPSTUF
/
GREPMAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1986-10-31
|
8KB
|
367 lines
/*
Grep-Wc
Grep - Globally search for Regular Expressions and Print, i.e.,
g/r.e./p
Wc - char, word, line/paragraph count
Works on text or MacWrite files
Special characters for patterns
^ Match beginning of line (if at beginning of pattern)
$ Match end of line (if at end of pattern)
. Match any character
[..] Match class of characters. If first character following
the [ is ^, match all BUT the range of characters. A range
of characters may be specified by separating them with a
dash, e.g., [a-z]. The dash itself may be included as a class
member by giving it as the first class char (e.g., [-a-z]).
* Match any number of preceding things (if does not follow
*, ^ or $)
Characters which have special meanings only in certain places in
the pattern do not have that meaning elsewhere. Special meaning
may be turned off otherwise by escaping it with '\'. The backslash
may be entered into a pattern by doubling it.
Paul DuBois
Wisconsin Regional Primate Research Center
1220 Capitol Court
University of Wisconsin-Madison
Madison, WI 53706 USA
UUCP: {allegra, ihnp4, seismo}!uwvax!uwmacc!dubois
ARPA: dubois@rhesus.primate.wisc.edu
dubois@unix.macc.wisc.edu
Version 1.0 12 March 1986 (written in Rascal)
Version 1.1 22 August 1986 (written in LightspeedC)
Fixed:
Menu goes away when window not active.
Can be selected from Apple menu while open w/o crashing.
Doesn't pass handle-ized rects to ToolBox routines.
Upper limits on window sizing are machine sensitive.
Always uses System file Get/PutFile dialogs (e.g., in MacWrite).
*/
# include "Grep.h"
# include <DeviceMgr.h>
# include <EventMgr.h>
# include <MenuMgr.h>
# include <FileMgr.h>
/* global variables */
Boolean isOpen = false; /* true if DA already open */
WindowPtr theWind;
DCtlPtr dce;
int dCtlRefNum;
TEHandle teHand;
MenuHandle theMenu;
Rect growRect;
int resBase; /* base DA resource number */
Boolean fileOpen = false; /* whether output file is open */
int outFile; /* output file reference number */
/*
search options
*/
Boolean prtMatches = true; /* true: print lines w/pattern */
Boolean prtLineNum = false; /* print line numbers if true */
Boolean ignoreCase = false; /* ignore letter case if true */
/*
other information about search
*/
Boolean grepping; /* true if currently searching */
Boolean paused; /* true if pause button was hit */
Boolean havePat = true; /* whether have good pattern or not */
ControlHandle pauseCtl;
ControlHandle cancelCtl;
Alarm (mesg)
StringPtr mesg;
{
ParamText (mesg, "\p", "\p", "\p");
(void) Alert (resBase + alarmBox, nil);
}
/*
Redraw the window. It is assumed that the port is set correctly.
The ValidRect is done because sometimes this is called before any
update event is obtained. The ValidRect cancels any that might be
pending, preventing two redraws.
*/
Update ()
{
Rect r;
DrawControls (theWind);
MoveTo (0, 24);
LineTo (30000, 24);
r = (**teHand).viewRect;
TEUpdate (&r, teHand);
ValidRect (&theWind->portRect);
}
FiddleMenu (activate)
Boolean activate;
{
if (activate)
InsertMenu (theMenu, 0);
else
DeleteMenu (dCtlRefNum);
DrawMenuBar ();
}
main(p, d, n)
register cntrlParam *p; /* ==> parameter block */
register DCtlPtr d; /* ==> device control entry */
int n; /* entry point selector */
{
Point thePt;
Rect r;
EventRecord *theEvent;
ControlHandle ctl;
dCtlRefNum = (dce = d)->dCtlRefNum;
/* check to make sure data area was allocated */
if (d->dCtlStorage == 0)
{
if (n == 0) /* open */
CloseDriver(dCtlRefNum);
}
else switch (n) /* dispatch */
{
case 0: /* open */
/*
Need to set these values each time, because the OS resets
them before every call...
*/
d->dCtlFlags |= dNeedLock | dNeedTime | dNeedGoodBye;
d->dCtlDelay = 0;
d->dCtlEMask = updateEvt | activateEvt | mouseDown ;
d->dCtlMenu = dCtlRefNum;
/*
Check to see whether already open or not. If not, set up window,
window growing limits, etc. The SelectWindow is for the case where
the DA is already open but hidden behind some other window.
Selecting Grep from the DA menu when already open simply has the
effect of bringing it to the front.
*/
if (!isOpen)
{
isOpen = true;
theMenu = NewMenu (dCtlRefNum, "\pGrep-Wc");
AppendMenu (theMenu, "\pAbout Grep-Wc;(-;Count...");
AppendMenu (theMenu, "\pSearch...;Set Pattern...;Save Output...");
GetWMgrPort (&theWind);
growRect = theWind->portRect;
growRect.left = 180;
growRect.top = 60;
SetRect (&r, 25, 80, 490, 320);
theWind = NewWindow (nil, &r, "\pGrep-Wc", true,
documentProc, -1L, true, 0L);
((WindowPeek) theWind)->windowKind = dCtlRefNum;
SetPort (theWind);
TextFont (monaco);
TextSize (9);
/* Create TERec and build controls */
OffsetRect (&r, -r.left, -r.top); /* move to (0, 0) */
r.top += 25; /* leave room for buttons */
r.left += 6;
teHand = TENew (&r, &r);
(**teHand).crOnly = -1; /* no word wrap */
SetRect (&r, 5, 2, 85, 22);
pauseCtl =
NewControl (theWind, &r, "\pPause", true,
0, 0, 0, pushButProc, nil);
OffsetRect (&r, 90, 0);
cancelCtl =
NewControl (theWind, &r, "\pCancel", true,
0, 0, 0, pushButProc, nil);
GrepState (255); /* set grepping false, inactivate buttons */
/* determine base resource number */
resBase = 0xc000 + (~dCtlRefNum << 5);
}
SelectWindow (theWind);
break;
case 2: /* control */
SetPort (theWind);
switch (p->csCode)
{
case accEvent: /* need glasses for next statement */
theEvent = (EventRecord *) * (long *) &p->csParam;
switch (theEvent->what)
{
case activateEvt:
/*
Set up or destroy menu, depending
on activate type.
*/
FiddleMenu (theEvent->modifiers & activeFlag);
break;
case updateEvt:
BeginUpdate (theWind);
Update ();
EndUpdate (theWind);
break;
case mouseDown:
/*
Check mouse click and whether it's a window grow event.
Must do the test explicitly, since DA's don't get told about
clicks in the inGrow region.
*/
thePt = theEvent->where;
GlobalToLocal (&thePt);
r = theWind->portRect;
r.left = r.right - 15;
r.top = r.bottom - 15;
if (PtInRect (thePt, &r))
{
LocalToGlobal (&thePt);
* (long *) &thePt = GrowWindow (theWind, thePt, &growRect);
SizeWindow (theWind, thePt.h, thePt.v, true);
r = theWind->portRect;
ClipRect (&r);
/*InvalRect (&r); /* force update event */
/*
Reset the text viewRect. It's
not necessary to reset the destRect,
since only the top and left are
used, and they haven't changed.
*/
r.top += 25;
r.left += 6;
(**teHand).viewRect = r;
}
else if (FindControl (thePt, theWind, &ctl))
{
if (TrackControl (ctl, thePt, nil))
{
if (ctl == cancelCtl)
{
StopGrep ();
}
else if (ctl == pauseCtl)
{
if (paused)
SetCTitle (pauseCtl, "\pPause");
else
SetCTitle (pauseCtl, "\pResume");
paused = !paused;
}
}
}
break;
}
break;
case accMenu:
switch (* (int *) ((Ptr) &p->csParam + 2))
{
case about:
(void) Alert (resBase + aboutBox, nil);
break;
case count:
StopGrep (); /* terminate any ongoing grep operation */
if (GetStream ())
Wc ();
break;
case search:
StartGrep ();
break;
case setPattern:
GetGrepPat ();
break;
case saveOutput:
FileOutput ();
break;
}
HiliteMenu (0);
break;
case accRun:
if ((theWind == FrontWindow ()) && grepping)
GrepLine ();
break;
case goodBye:
CloseStream (); /* close any open input file */
if (fileOpen) /* close output file if open */
FileOutput ();
break;
}
break;
case 4: /* close */
CloseStream (); /* close any open input file */
if (fileOpen) /* close output file if open */
FileOutput ();
FiddleMenu (false);
DisposeMenu (theMenu); /* toss menu */
TEDispose (teHand); /* toss text record */
DisposeWindow (theWind); /* get rid of window and controls */
break;
}
/* done */
return (0);
}